#!/usr/bin/env node
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const fs = require('fs-extra');
const path = require('path');

const app = express();
const DEFAULT_PORT = 3000;

// 解析命令行参数
const args = process.argv.slice(2);
const getPathFromArgs = () => {
  const pathIndex = args.indexOf('--path');
  const dirIndex = args.indexOf('--dir');
  const storageIndex = args.indexOf('--storage');
  
  if (pathIndex !== -1 && args[pathIndex + 1]) {
    return args[pathIndex + 1];
  }
  if (dirIndex !== -1 && args[dirIndex + 1]) {
    return args[dirIndex + 1];
  }
  if (storageIndex !== -1 && args[storageIndex + 1]) {
    return args[storageIndex + 1];
  }
  return null;
};

// 默认存储路径（优先级：命令行参数 > 环境变量 > 默认路径）
const DEFAULT_STORAGE_PATH = getPathFromArgs() || process.env.NOTE_STORAGE_PATH || path.join(__dirname, '..', 'note_files');

// 确保默认存储路径存在
fs.ensureDirSync(DEFAULT_STORAGE_PATH);

// 中间件
app.use(cors());
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '..', 'public')));

// 1. 返回前端静态资源 - 已通过express.static实现

// 3. 目录操作接口
// 新建目录
app.post('/api/create/directory', async (req, res) => {
  try {
    const { directoryName, parentPath = '' } = req.body;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, parentPath, directoryName);
    
    // 同名校验
    const pathExists = await fs.pathExists(fullPath);
    if (pathExists) {
      return res.status(400).json({ success: false, message: '目录已存在，请使用其他名称' });
    }
    
    await fs.ensureDir(fullPath);
    res.json({ success: true, message: '目录创建成功', path: fullPath });
  } catch (error) {
    res.status(500).json({ success: false, message: '目录创建失败', error: error.message });
  }
});

// 修改目录（重命名）
app.post('/api/update/directory', async (req, res) => {
  try {
    const { oldPath, newPath } = req.body;
    const fullOldPath = path.join(DEFAULT_STORAGE_PATH, oldPath);
    const fullNewPath = path.join(DEFAULT_STORAGE_PATH, newPath);
    
    console.log('oldPath', fullOldPath);
    console.log('newPath', fullNewPath);
    
    // 检查源目录是否存在
    const sourceExists = await fs.pathExists(fullOldPath);
    console.log('sourceExists', sourceExists);
    if (!sourceExists) {
      return res.status(400).json({ success: false, message: '源目录不存在' });
    }
    
    // 同名校验
    const pathExists = await fs.pathExists(fullNewPath);
    console.log('pathExists', pathExists);
    if (pathExists) {
      return res.status(400).json({ success: false, message: '目标目录已存在，请使用其他名称' });
    }
    
    // 检查文件夹内容（调试信息）
    const stats = await fs.stat(fullOldPath);
    console.log('文件夹大小:', stats.size);
    
    if (stats.isDirectory()) {
      const items = await fs.readdir(fullOldPath);
      console.log('文件夹包含项目数量:', items.length);
    }
    
    // 使用复制+删除替代移动操作
    console.log('开始复制文件夹...');
    await fs.copy(fullOldPath, fullNewPath);
    console.log('复制完成，开始删除原文件夹...');
    await fs.remove(fullOldPath);
    console.log('删除完成');
    
    res.json({ success: true, message: '目录重命名成功' });
  } catch (error) {
    console.error('重命名错误:', error);
    res.status(500).json({ success: false, message: '目录重命名失败', error: error.message });
  }
});

// 删除目录
app.post('/api/delete/directory', async (req, res) => {
  try {
    const { directoryPath } = req.body;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, directoryPath);
    
    // 检查目录内容
    const stats = await fs.stat(fullPath);
    console.log('目录大小:', stats.size);
    
    if (stats.isDirectory()) {
      const items = await fs.readdir(fullPath);
      console.log('目录包含项目数量:', items.length);
    }
    
    // 添加超时处理
    const removePromise = fs.remove(fullPath);
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error('删除操作超时')), 60000); // 60秒超时
    });
    
    await Promise.race([removePromise, timeoutPromise]);
    
    res.json({ success: true, message: '目录删除成功' });
  } catch (error) {
    console.error('删除错误:', error);
    res.status(500).json({ success: false, message: '目录删除失败', error: error.message });
  }
});

// 获取目录列表
app.get('/api/list/directories', async (req, res) => {
  try {
    const { parentPath = '' } = req.query;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, parentPath);
    
    const items = await fs.readdir(fullPath);
    const directories = [];
    
    for (const item of items) {
      const itemPath = path.join(fullPath, item);
      const stat = await fs.stat(itemPath);
      
      if (stat.isDirectory()) {
        directories.push({
          name: item,
          path: path.join(parentPath, item),
          createdAt: stat.birthtime
        });
      }
    }
    
    res.json({ success: true, directories });
  } catch (error) {
    res.status(500).json({ success: false, message: '获取目录列表失败', error: error.message });
  }
});

// 4. Note文件操作接口
// 新建Note文件
app.post('/api/create/note', async (req, res) => {
  try {
    const { fileName, directoryPath = '', content = '' } = req.body;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, directoryPath, fileName);
    
    // 确保文件名以.md结尾
    const finalFileName = fileName.endsWith('.md') ? fileName : `${fileName}.md`;
    const finalPath = path.join(DEFAULT_STORAGE_PATH, directoryPath, finalFileName);
    
    // 同名校验
    const pathExists = await fs.pathExists(finalPath);
    if (pathExists) {
      return res.status(400).json({ success: false, message: '文件已存在，请使用其他名称' });
    }
    
    await fs.writeFile(finalPath, content);
    res.json({ success: true, message: 'Note文件创建成功', path: finalPath });
  } catch (error) {
    res.status(500).json({ success: false, message: 'Note文件创建失败', error: error.message });
  }
});

// 重命名Note文件
app.post('/api/rename/note', async (req, res) => {
  try {
    const { oldPath, newPath } = req.body;
    const fullOldPath = path.join(DEFAULT_STORAGE_PATH, oldPath);
    const fullNewPath = path.join(DEFAULT_STORAGE_PATH, newPath);
    
    // 同名校验
    const pathExists = await fs.pathExists(fullNewPath);
    if (pathExists) {
      return res.status(400).json({ success: false, message: '目标文件已存在，请使用其他名称' });
    }
    
    // 检查文件大小
    const stats = await fs.stat(fullOldPath);
    console.log('文件大小:', stats.size, 'bytes');
    
    // 使用复制+删除替代移动操作
    await fs.copy(fullOldPath, fullNewPath);
    await fs.remove(fullOldPath);
    
    res.json({ success: true, message: 'Note文件重命名成功' });
  } catch (error) {
    console.error('重命名错误:', error);
    res.status(500).json({ success: false, message: 'Note文件重命名失败', error: error.message });
  }
});

// 修改Note文件内容
app.post('/api/update/note', async (req, res) => {
  try {
    const { filePath, content } = req.body;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, filePath);
    
    await fs.writeFile(fullPath, content);
    res.json({ success: true, message: 'Note文件更新成功' });
  } catch (error) {
    res.status(500).json({ success: false, message: 'Note文件更新失败', error: error.message });
  }
});

// 删除Note文件
app.post('/api/delete/note', async (req, res) => {
  try {
    const { filePath } = req.body;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, filePath);
    
    await fs.remove(fullPath);
    res.json({ success: true, message: 'Note文件删除成功' });
  } catch (error) {
    res.status(500).json({ success: false, message: 'Note文件删除失败', error: error.message });
  }
});

// 获取Note文件内容
app.get('/api/get/note', async (req, res) => {
  try {
    const { filePath } = req.query;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, filePath);
    
    // 检查文件大小
    const stats = await fs.stat(fullPath);
    console.log('文件大小:', stats.size, 'bytes');
    
    // 限制文件大小，避免过大文件导致超时
    const maxSize = 10 * 1024 * 1024; // 10MB
    if (stats.size > maxSize) {
      return res.status(400).json({ 
        success: false, 
        message: '文件过大，请使用小于10MB的文件' 
      });
    }
    
    // 添加超时处理
    const readPromise = fs.readFile(fullPath, 'utf8');
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error('读取文件超时')), 15000); // 15秒超时
    });
    
    const content = await Promise.race([readPromise, timeoutPromise]);
    
    res.json({ success: true, content });
  } catch (error) {
    console.error('读取文件错误:', error);
    res.status(500).json({ success: false, message: '获取Note文件内容失败', error: error.message });
  }
});

// 获取文件列表
app.get('/api/list/all', async (req, res) => {
  try {
    const { parentPath = '' } = req.query;
    const fullPath = path.join(DEFAULT_STORAGE_PATH, parentPath);
    
    // 添加超时处理
    const listPromise = async () => {
      const items = await fs.readdir(fullPath);
      const directories = [];
      const files = [];
      
      // 限制处理的文件数量，避免过多文件导致超时
      const maxItems = 1000;
      const processedItems = items.slice(0, maxItems);
      
      for (const item of processedItems) {
        const itemPath = path.join(fullPath, item);
        const stat = await fs.stat(itemPath);
        
        if (stat.isDirectory()) {
          directories.push({
            name: item,
            path: path.join(parentPath, item),
            createdAt: stat.birthtime
          });
        } else if (stat.isFile() && item.endsWith('.md')) {
          files.push({
            name: item,
            path: path.join(parentPath, item),
            createdAt: stat.birthtime,
            updatedAt: stat.mtime
          });
        }
      }
      
      return { directories, files, totalItems: items.length, processedItems: processedItems.length };
    };
    
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error('获取文件列表超时')), 30000); // 30秒超时
    });
    
    const result = await Promise.race([listPromise(), timeoutPromise]);
    
    res.json({ 
      success: true, 
      directories: result.directories,
      files: result.files,
      totalItems: result.totalItems,
      processedItems: result.processedItems,
      truncated: result.totalItems > result.processedItems
    });
  } catch (error) {
    console.error('获取文件列表错误:', error);
    res.status(500).json({ 
      success: false, 
      message: '获取文件和目录列表失败', 
      error: error.message 
    });
  }
});

// 显示帮助信息
const showHelp = () => {
  console.log(`\nNote Editor Server CLI\n`);
  console.log(`用法: note-server [选项]\n`);
  console.log(`选项:`);
  console.log(`  --path <路径>     设置Note文件存储路径`);
  console.log(`  --dir <路径>      设置Note文件存储路径（别名）`);
  console.log(`  --storage <路径>  设置Note文件存储路径（别名）`);
  console.log(`  --port <端口>     设置服务器端口（默认: 3000）`);
  console.log(`  --help, -h        显示帮助信息\n`);
  console.log(`环境变量:`);
  console.log(`  NOTE_STORAGE_PATH  设置Note文件存储路径`);
  console.log(`  PORT                 设置服务器端口\n`);
  console.log(`示例:`);
  console.log(`  note-server --path /path/to/note/files`);
  console.log(`  note-server --port 8080`);
  console.log(`  NOTE_STORAGE_PATH=/docs note-server\n`);
  process.exit(0);
};

// 检查帮助参数
if (args.includes('--help') || args.includes('-h')) {
  showHelp();
}

// 解析端口参数
const getPortFromArgs = () => {
  const portIndex = args.indexOf('--port');
  if (portIndex !== -1 && args[portIndex + 1]) {
    const port = parseInt(args[portIndex + 1]);
    return isNaN(port) ? null : port;
  }
  return null;
};

const SERVER_PORT = getPortFromArgs() || process.env.PORT || DEFAULT_PORT;

// 启动服务器
app.listen(SERVER_PORT, () => {
  console.log(`\n🚀 Note Editor Server 已启动!`);
  console.log(`🌐 服务器地址: http://localhost:${SERVER_PORT}`);
  console.log(`📁 存储路径: ${DEFAULT_STORAGE_PATH}`);
  console.log(`\n💡 提示: 使用 --help 查看所有选项\n`);
});